﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Serialization;
using System.Runtime.Serialization;
using System.Xml;
using InstantSpine.Core;
using InstantSpine.Core.MaterialModels;

namespace InstantSpine.Tests
{
    public class Sub
    {
        public int? Val1 { get; set; }
        public string Val2 { get; set; }
        public List<int> Ints { get; set; }
    }

    public class Base
    {
        public Sub Subbi { get; set; }
        public bool IsSet { get; set; }
    }

    [DataContract]
    public class SomeData
    {
        [DataMember]
        public int MyProp {
            get;
            private set;
        }

        public SomeData(int i) {
            MyProp = i;
        }
    }

    class Program
    {
        static async Task DoIt() {
            await Task.Run(() => Thread.Sleep(200));
            Console.WriteLine("Done sleeping");
        }

        static void Main(string[] args) {
            var sd = new SomeData(3);
            var sdSer = new DataContractSerializer(typeof(SomeData));
            var xws = new XmlWriterSettings();
            using (XmlWriter xw = XmlWriter.Create("somedata.xml", xws),
                             xdw = XmlDictionaryWriter.CreateDictionaryWriter(xw))
            {
                sdSer.WriteObject(xdw, sd);            
            }

            SomeData sd2;
            using (XmlReader xr = XmlReader.Create("somedata.xml"),
                             xdr = XmlDictionaryReader.CreateDictionaryReader(xr)) {
                sd2 = (SomeData)sdSer.ReadObject(xdr);
            }
            Console.WriteLine(sd2.MyProp);

            var t = DoIt();
            t.Wait();
            
            var nhm = new NeoHookeanMaterial(0.3, 1.2, "mymat");            
            nhm.PropertyChanged += (_, pargs) => Console.WriteLine(pargs.PropertyName);            
            nhm.C10 = 0.31;
            nhm.D1 = 1.0;
            var nhm2 = nhm;
            nhm2.C10 = 0.5;
            nhm2.C10 = 0.3;

            var afl = new AnnulusFiberLayer("layer1");
            afl.FiberMaterialProperties.UniaxialTestData.Add(new StressStrainPair(10.0, 0.3));
            afl.FiberMaterialProperties.UniaxialTestData.Add(Tuple.Create(13.0, 0.33));

            var fibs = new LayeredAnnulusFibers(afl, afl, afl, afl, afl, afl, afl, afl, "annulus1");
            var f7eps = fibs.Layer7.FiberMaterialProperties.UniaxialTestData[0].Strain;
            var f7sig = fibs.Layer7.FiberMaterialProperties.UniaxialTestData[0].Stress;

            // create default instance, mutated/updated by user interaction with the GUI
            // via (two-way) data-binding
            var sm = new SpineModel();
            sm.Materials.Spongiosa.PropertyChanged += (_, e) => Console.WriteLine(e.PropertyName);
            sm.Anatomy.VertebraeAndDiscs.CollectionChanged += (s, e) => Console.WriteLine("Collection changed: {0}", e.Action);

            sm.Anatomy.VertebraeAndDiscs.Add(new VertebraDiscCompound());
            sm.Anatomy.VertebraeAndDiscs[0].PropertyChanged += 
                (vb, e) => Console.WriteLine("{0} = {1} mm", e.PropertyName, ((VertebraDiscCompound)vb).DiscHeight);

            sm.Anatomy.VertebraeAndDiscs[0].DiscHeight = 30.0;
            sm.Anatomy.VertebraeAndDiscs[0].VertebraID = 4;
            sm.Materials.Spongiosa.PoissonsRatio = 0.3;

            // Start Word
            //var wordType = Type.GetTypeFromProgID("Word.Application");
            //dynamic wordApp = Activator.CreateInstance(wordType);            
            //wordApp.Visible = true;

            var b = new Base { IsSet = true, Subbi = new Sub { Val1 = null, Val2 = "huhu", Ints = new List<int> { 1, 2, 3 } } };
            var ser = new XmlSerializer(typeof(Base));
            ser.Serialize(Console.Out, b);

            Console.WriteLine();
            Console.WriteLine("{0} = {1}", VertebraIDs.T10, (int)VertebraIDs.T10);            
        }

        static void foo(SpineModel model) {
            var vb1 = model.Anatomy.VertebraeAndDiscs[0];            
            var epds = vb1.EndplateDepthInferior;
        }
    }
}
